home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / RKMLibsPrgs / graphics_libraries / sprites_bobs / anim.c < prev    next >
C/C++ Source or Header  |  1992-09-03  |  28KB  |  946 lines

  1. ;/* Anim.c - Animation example -- works with 1.3 and later.
  2. If EXISTS animtools.c
  3.     LC -b1 -cfist -v -j73 animtools.c  ;  Create AnimTools object file
  4. Else
  5.     Echo "Requires animtools.c (which isn't here) in order to compile."
  6.     Quit
  7. EndIf
  8. LC -b1 -cfist -v -j73 anim.c
  9. Blink FROM LIB:c.o,animtools.o,anim.o TO anim LIBRARY LIB:LC.lib,LIB:Amiga.lib
  10. Quit ;
  11.  
  12.  
  13. Copyright (c) 1992 Commodore-Amiga, Inc.
  14.  
  15. This example is provided in electronic form by Commodore-Amiga, Inc. for
  16. use with the "Amiga ROM Kernel Reference Manual: Libraries", 3rd Edition,
  17. published by Addison-Wesley (ISBN 0-201-56774-1).
  18.  
  19. The "Amiga ROM Kernel Reference Manual: Libraries" contains additional
  20. information on the correct usage of the techniques and operating system
  21. functions presented in these examples.  The source and executable code
  22. of these examples may only be distributed in free electronic form, via
  23. bulletin board or as part of a fully non-commercial and freely
  24. redistributable diskette.  Both the source and executable code (including
  25. comments) must be included, without modification, in any copy.  This
  26. example may not be published in printed form or distributed with any
  27. commercial product.  However, the programming techniques and support
  28. routines set forth in these examples may be used in the development
  29. of original executable software products for Commodore Amiga computers.
  30.  
  31. All other rights reserved.
  32.  
  33. This example is provided "as-is" and is subject to change; no
  34. warranties are made.  All use is at your own risk. No liability or
  35. responsibility is assumed.
  36.  
  37. */
  38.  
  39. #include <exec/types.h>
  40. #include <exec/memory.h>
  41. #include <intuition/intuitionbase.h>
  42. #include <graphics/gfx.h>
  43. #include <graphics/gfxbase.h>
  44. #include <graphics/gels.h>
  45.  
  46. #include "animtools.h"
  47. #include "animtools_proto.h"
  48.  
  49. #include <stdlib.h>
  50. #include <stdio.h>
  51.  
  52. int CXBRK(void) { return(0); } /* disable lattice CTRL-C handling */
  53.  
  54. /*--------------------------------------------------------------*/
  55. /*                                                              */
  56. /*--------------------------------------------------------------*/
  57. struct AnimOb *setupBoing(SHORT dbufing);
  58. struct AnimOb *setupMan(SHORT dbufing);
  59. struct AnimOb *setupWorm(SHORT dbufing);
  60.  
  61. WORD anEdgeORoutine(struct AnimOb *anOb);
  62. WORD bounceORoutine(struct AnimOb *anOb);
  63. WORD goInFrontOfHead(struct AnimComp *aComp);
  64. WORD goBehindHead(struct AnimComp *aComp);
  65.  
  66. VOID runAnimation(struct Window *win, SHORT dbufing,
  67.                   struct AnimOb **animKey, struct BitMap **myBitMaps);
  68.  
  69. LONG setupPlanes(struct BitMap *bitMap, LONG depth, LONG width, LONG height);
  70. struct BitMap **setupBitMaps(LONG depth, LONG width, LONG height);
  71. VOID freePlanes(struct BitMap *bitMap, LONG depth, LONG width, LONG height);
  72. VOID freeBitMaps(struct BitMap **myBitMaps,
  73.                     LONG depth, LONG width, LONG height);
  74.  
  75. struct GelsInfo *setupDisplay(struct Window **win,
  76.                               SHORT dbufing, struct BitMap **myBitMaps);
  77. VOID DrawGels(struct Window *win, struct AnimOb **animKey, SHORT dbufing,
  78.               WORD *toggleFrame, struct BitMap **myBitMaps);
  79.  
  80. /*--------------------------------------------------------------*/
  81. /*                                                              */
  82. /*--------------------------------------------------------------*/
  83. #define ANFS    ANFRACSIZE
  84. #define BNFS    (ANFRACSIZE-2)
  85. #define CNFS    (ANFRACSIZE-2)
  86.  
  87. /* These are used for MeMask (1 << ID_xxx) */
  88. #define ID_BORDER 0
  89. #define ID_WRM    3
  90. #define ID_BNG    4
  91. #define ID_MAN    5
  92.  
  93. #define SBMWIDTH  320  /* My screen size constants. */
  94. #define SBMHEIGHT 200
  95. #define SBMDEPTH    4
  96. #define SCRNMODE NULL  /* (HIRES | LACE) for NewScreen, ends up in view.*/
  97.  
  98. #define RBMWIDTH  320  /* My raster size constants. (These CAN differ) */
  99. #define RBMHEIGHT 200
  100. #define RBMDEPTH    4
  101.  
  102. /*--------------------------------------------------------------*/
  103. /*                                                              */
  104. /*--------------------------------------------------------------*/
  105. struct NewScreen ns =
  106.     {
  107.     0, 0, SBMWIDTH, SBMHEIGHT, SBMDEPTH, 0, 0, SCRNMODE,
  108.     CUSTOMSCREEN | SCREENQUIET, NULL, NULL, NULL, NULL
  109.     };
  110.  
  111. /* this is a little window that will let us get a CLOSEWINDOW message */
  112. struct NewWindow nw =
  113.     {
  114.     0, 0, 25, 12, 0, 0, CLOSEWINDOW,
  115.     WINDOWCLOSE | BORDERLESS | RMBTRAP, NULL, NULL, NULL, NULL,
  116.     NULL, 0, 0, SBMWIDTH, SBMHEIGHT-1, CUSTOMSCREEN
  117.     };
  118.  
  119. struct IntuitionBase *IntuitionBase    = NULL;
  120. struct GfxBase         *GfxBase        = NULL;
  121.  
  122. int return_code;
  123.  
  124. #include "anim_images.h"
  125. /*--------------------------------------------------------------*/
  126. /* Structures for the worm sequence.                            */
  127. /*--------------------------------------------------------------*/
  128.  
  129. NEWBOB newWrmBob =
  130.     {
  131.     NULL,                /* nb_Image - image is null for sequences    */
  132.                         /*              data comes from NEWANIMSEQ    */
  133.     WRMWWIDTH,            /* nb_WordWidth - width of the bob            */
  134.     WRMHEIGHT,            /* nb_LineHeight - height of the bob        */
  135.     WRMDEPTH,            /* nb_ImageDepth - depth of image data        */
  136.     0x3,                /* nb_PlanePick - planes to put data in        */
  137.     0x0,                /* nb_PlaneOnOff - empty planes to set        */
  138.     SAVEBACK | OVERLAY,    /* nb_BFlags - flags for the bob            */
  139.     0,                    /* nb_DBuf - 1=dbuf, 0=not dbuf                */
  140.     RBMDEPTH,            /* nb_RasDepth - num planes in raster        */
  141.     0,                    /* nb_X - bob x position                    */
  142.     0,                    /* nb_Y - bob y position                    */
  143.     (1L << ID_BORDER),    /* nb_HitMask - hit mask                    */
  144.     (1L << ID_WRM),        /* nb_MeMask - me mask                        */
  145.     };
  146. NEWANIMSEQ newWrmSeq =
  147.     {
  148.     NULL,                /* nas_HeadOb - head object for the seq        */
  149.     (WORD *)WrmImage,    /* nas_Images - array of images                */
  150.     WrmXTranses,        /* nas_Xt - x offsets from central object    */
  151.     WrmYTranses,        /* nas_Yt - y offsets from central object    */
  152.     WrmTimes,            /* nas_Times - timing values for objects    */
  153.     WrmCRoutines,        /* nas_Routines - array of comp routines    */
  154.     0,                    /* nas_CFlags - comp flags                    */
  155.     WRMCOUNT,            /* nas_Count - number of comps in sequence    */
  156.     0,                    /* nas_SingleImage - 1=single image for seq.*/
  157.                         /*                     0=multiple images      */
  158.     };
  159.  
  160. /*--------------------------------------------------------------*/
  161. /* Structures for the man sequence                              */
  162. /*--------------------------------------------------------------*/
  163.  
  164. NEWBOB newNearLegBob =
  165.     {
  166.     NULL, MANLWWIDTH, MANLHEIGHT, MANLDEPTH, 0x3, 0xC,
  167.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_MAN),
  168.     };
  169. NEWANIMSEQ newNearLegSeq =
  170.     {
  171.     NULL, (WORD *)manLImage, manLXTranses, manLYTranses, manLTimes,
  172.     manLCRoutines, 0, MANLCOUNT, 0,
  173.     };
  174.  
  175. NEWBOB newFarLegBob =
  176.     {
  177.     NULL, MANLWWIDTH, MANLHEIGHT, MANLDEPTH, 0x3, 0x8,
  178.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_MAN),
  179.     };
  180. NEWANIMSEQ newFarLegSeq =
  181.     {
  182.     NULL, (WORD *)manLImage, manLXTranses, manLYTranses, manLTimes,
  183.     manLCRoutines, 0, MANLCOUNT, 0,
  184.     };
  185.  
  186. NEWBOB newNearArmBob =
  187.     {
  188.     NULL, MANAWWIDTH, MANAHEIGHT, MANADEPTH, 0x3, 0xC,
  189.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_MAN),
  190.     };
  191. NEWANIMSEQ newNearArmSeq =
  192.     {
  193.     NULL, (WORD *)manAImage, manAXTranses, manAYTranses, manATimes,
  194.     manACRoutines, 0, MANACOUNT, 0,
  195.     };
  196.  
  197. NEWBOB newFarArmBob =
  198.     {
  199.     NULL, MANAWWIDTH, MANAHEIGHT, MANADEPTH, 0x3, 0x8,
  200.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_MAN),
  201.     };
  202. NEWANIMSEQ newFarArmSeq =
  203.     {
  204.     NULL, (WORD *)manAImage, manAXTranses, manAYTranses, manATimes,
  205.     manACRoutines, 0, MANACOUNT, 0,
  206.     };
  207.  
  208. NEWBOB newTrunkBob =
  209.     {
  210.     NULL, MANTWWIDTH, MANTHEIGHT, MANTDEPTH, 0x3, 0xC,
  211.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_MAN),
  212.     };
  213. NEWANIMSEQ newTrunkSeq =
  214.     {
  215.     NULL, (WORD *)manTImage, manTXTranses, manTYTranses, manTTimes,
  216.     manTCRoutines, 0, MANTCOUNT, 0,
  217.     };
  218.  
  219. /*--------------------------------------------------------------*/
  220. /* Structures for the boing ball and satellites.                */
  221. /*--------------------------------------------------------------*/
  222.  
  223. NEWBOB newBoingBob =
  224.     {
  225.     NULL, BNG3WWIDTH, BNG3HEIGHT, BNG3DEPTH, 0xD, 0x2,
  226.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_BNG),
  227.     };
  228. NEWANIMSEQ newBoingSeq =
  229.     {
  230.     NULL, (WORD *)boing3Image, boing3XTranses, boing3YTranses,
  231.     boing3Times, boing3CRoutines, 0, BNG3COUNT, 0,
  232.     };
  233.  
  234. NEWBOB newSatABob =
  235.     {
  236.     NULL, SATWWIDTH, SATHEIGHT, SATDEPTH, 0xC, 0x0,
  237.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_BNG),
  238.     };
  239. NEWANIMSEQ newSatASeq =
  240.     {
  241.     NULL, (WORD *)satImage, satAXTranses, satAYTranses,
  242.     satTimes, satACRoutines, 0, SATCOUNT, 1,
  243.     };
  244. NEWBOB newSatBBob =
  245.     {
  246.     NULL, SATWWIDTH, SATHEIGHT, SATDEPTH, 0xC, 0x3,
  247.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_BNG),
  248.     };
  249. NEWANIMSEQ newSatBSeq =
  250.     {
  251.     NULL, (WORD *)satImage, satBXTranses, satBYTranses,
  252.     satTimes, satBCRoutines, 0, SATCOUNT, 1,
  253.     };
  254. NEWBOB newSatCBob =
  255.     {
  256.     NULL, SATWWIDTH, SATHEIGHT, SATDEPTH, 0x3, 0x0,
  257.     SAVEBACK | OVERLAY, 0, RBMDEPTH, 0,0, (1L<<ID_BORDER), (1L<<ID_BNG),
  258.     };
  259. NEWANIMSEQ newSatCSeq =
  260.     {
  261.     NULL, (WORD *)satImage, satCXTranses, satCYTranses,
  262.     satTimes, satCCRoutines, 0, SATCOUNT, 1,
  263.     };
  264.  
  265. /*--------------------------------------------------------------*/
  266. /*--------------------------------------------------------------*/
  267. /*                      PROCEDURES                              */
  268. /*--------------------------------------------------------------*/
  269. /*--------------------------------------------------------------*/
  270.  
  271. /*--------------------------------------------------------------
  272. ** setupBoing() - allocate and initialize an object that will
  273. ** display as a boing ball with orbiting sattellites.
  274. **
  275. ** this is an animation object with four animation sequences.
  276. ** (boing and three sattellites.)
  277. ** (note that the sattellites all share the same single image data.)
  278. **
  279. ** return NULL on failure.
  280. */
  281. struct AnimOb *setupBoing(SHORT dbufing)
  282. {
  283. struct AnimOb    *bngOb;
  284. struct AnimComp *bngComp;
  285. struct AnimComp *satAComp;
  286. struct AnimComp *satBComp;
  287. struct AnimComp *satCComp;
  288.  
  289. if (NULL != (bngOb = AllocMem((LONG)sizeof(struct AnimOb), MEMF_CLEAR)))
  290.     {
  291.     bngOb->NextOb        = NULL;
  292.     bngOb->PrevOb        = NULL;
  293.     bngOb->Clock        = 0;
  294.     bngOb->AnY            = 50;
  295.     bngOb->AnX            = 50;
  296.     bngOb->AnOldY        = bngOb->AnY;
  297.     bngOb->AnOldX        = bngOb->AnX;
  298.     bngOb->YVel            = 3 << ANFRACSIZE;
  299.     bngOb->XVel            = 3 << ANFRACSIZE;
  300.     bngOb->YAccel        = 0;
  301.     bngOb->XAccel        = 0;
  302.     bngOb->RingYTrans    = BNG3RINGY << ANFRACSIZE;
  303.     bngOb->RingXTrans    = BNG3RINGX << ANFRACSIZE;
  304.     bngOb->AnimORoutine    = bounceORoutine;
  305.     bngOb->AUserExt        = 0;
  306.  
  307.     newBoingBob.nb_DBuf    = dbufing;
  308.     newBoingSeq.nas_HeadOb = bngOb;
  309.  
  310.     satACRoutines[4]      = goInFrontOfHead;
  311.     satACRoutines[12]      = goBehindHead;
  312.     satBCRoutines[8]      = goInFrontOfHead;
  313.     satBCRoutines[0]      = goBehindHead;
  314.     satCCRoutines[4]      = goInFrontOfHead;
  315.     satCCRoutines[12]     = goBehindHead;
  316.  
  317.     newSatABob.nb_DBuf      = dbufing;
  318.     newSatBBob.nb_DBuf      = dbufing;
  319.     newSatCBob.nb_DBuf      = dbufing;
  320.     newSatASeq.nas_HeadOb = bngOb;
  321.     newSatBSeq.nas_HeadOb = bngOb;
  322.     newSatCSeq.nas_HeadOb = bngOb;
  323.  
  324.     if (NULL != (bngComp = makeSeq(&newBoingBob, &newBoingSeq)))
  325.         {
  326.         bngComp->Flags |= RINGTRIGGER;
  327.         bngOb->HeadComp = bngComp;
  328.  
  329.         if (NULL != (satAComp = makeSeq(&newSatABob, &newSatASeq)))
  330.             {
  331.             bngComp->AnimBob->Before = satAComp->AnimBob;
  332.             satAComp->AnimBob->After = bngComp->AnimBob;
  333.  
  334.             if (NULL != (satBComp = makeSeq(&newSatBBob, &newSatBSeq)))
  335.                 {
  336.                 satAComp->AnimBob->Before = satBComp->AnimBob;
  337.                 satBComp->AnimBob->After = satAComp->AnimBob;
  338.  
  339.                 if (NULL != (satCComp = makeSeq(&newSatCBob, &newSatCSeq)))
  340.                     {
  341.                     satBComp->AnimBob->Before = satCComp->AnimBob;
  342.                     satCComp->AnimBob->After = satBComp->AnimBob;
  343.  
  344.                     bngComp->NextComp  = satAComp;
  345.                     bngComp->PrevComp  = NULL;
  346.  
  347.                     satAComp->NextComp = satBComp;
  348.                     satAComp->PrevComp = bngComp;
  349.  
  350.                     satBComp->NextComp = satCComp;
  351.                     satBComp->PrevComp = satAComp;
  352.  
  353.                     satCComp->NextComp = NULL;
  354.                     satCComp->PrevComp = satBComp;
  355.  
  356.                     return(bngOb);
  357.                     }
  358.                 freeSeq(satBComp,RBMDEPTH);
  359.                 }
  360.             freeSeq(satAComp,RBMDEPTH);
  361.             }
  362.         freeSeq(bngComp,RBMDEPTH);
  363.         }
  364.     FreeMem(bngOb, (LONG)sizeof(struct AnimOb));
  365.     }
  366. return_code = RETURN_WARN;
  367. return(NULL);
  368. }
  369.  
  370. /*--------------------------------------------------------------
  371. ** setupMan() - allocate and initialize an object that will
  372. ** display as a walking man.
  373. **
  374. ** this is an animation object with five animation sequences.
  375. ** (body, two arms and two legs.)
  376. **
  377. ** return NULL on failure.
  378. */
  379. struct AnimOb *setupMan(SHORT dbufing)
  380. {
  381. struct AnimOb *manOb;
  382.  
  383. struct AnimComp *trunkComp;
  384. struct AnimComp *farArmComp;
  385. struct AnimComp *farLegComp;
  386. struct AnimComp *nearArmComp;
  387. struct AnimComp *nearLegComp;
  388.  
  389. if (NULL != (manOb = AllocMem((LONG)sizeof(struct AnimOb), MEMF_CLEAR)))
  390.     {
  391.     manOb->NextOb        = NULL;
  392.     manOb->PrevOb        = NULL;
  393.     manOb->Clock        = 0;
  394.     manOb->AnY            = ((2 * MANHEIGHT) << ANFRACSIZE);
  395.     manOb->AnX            = 0;
  396.     manOb->AnOldY        = manOb->AnY;
  397.     manOb->AnOldX        = manOb->AnX;
  398.     manOb->YVel            = 0;
  399.     manOb->XVel            = 0;
  400.     manOb->YAccel        = 0;
  401.     manOb->XAccel        = 0;
  402.     manOb->RingYTrans    = (MANRINGY << ANFRACSIZE);
  403.     manOb->RingXTrans    = (MANRINGX << ANFRACSIZE);
  404.     manOb->AnimORoutine    = anEdgeORoutine;
  405.     manOb->AUserExt        = 0;
  406.  
  407.     newTrunkBob.nb_DBuf   = dbufing;
  408.     newFarArmBob.nb_DBuf  = dbufing;
  409.     newFarLegBob.nb_DBuf  = dbufing;
  410.     newNearArmBob.nb_DBuf = dbufing;
  411.     newNearLegBob.nb_DBuf = dbufing;
  412.  
  413.     newTrunkSeq.nas_HeadOb   = manOb;
  414.     newFarArmSeq.nas_HeadOb  = manOb;
  415.     newFarLegSeq.nas_HeadOb  = manOb;
  416.     newNearArmSeq.nas_HeadOb = manOb;
  417.     newNearLegSeq.nas_HeadOb = manOb;
  418.  
  419.     if (NULL != (trunkComp = makeSeq(&newTrunkBob, &newTrunkSeq)))
  420.         {
  421.         trunkComp->Flags |= RINGTRIGGER;
  422.  
  423.         if (NULL != (farArmComp = makeSeq(&newFarArmBob, &newFarArmSeq)))
  424.             {
  425.             trunkComp->AnimBob->Before = farArmComp->AnimBob;
  426.             farArmComp->AnimBob->After = trunkComp->AnimBob;
  427.  
  428.             if (NULL != (farLegComp = makeSeq(&newFarLegBob, &newFarLegSeq)))
  429.                 {
  430.                 farArmComp->AnimBob->Before = farLegComp->AnimBob;
  431.                 farLegComp->AnimBob->After = farArmComp->AnimBob;
  432.  
  433.                 if (NULL != (nearArmComp =
  434.                             makeSeq(&newNearArmBob, &newNearArmSeq)))
  435.                     {
  436.                     nearArmComp =
  437.                         nearArmComp->NextSeq->NextSeq->NextSeq->NextSeq;
  438.                     farLegComp->AnimBob->Before = nearArmComp->AnimBob;
  439.                     nearArmComp->AnimBob->After = farLegComp->AnimBob;
  440.  
  441.                     if (NULL != (nearLegComp =
  442.                                     makeSeq(&newNearLegBob, &newNearLegSeq)))
  443.                         {
  444.                         nearLegComp =
  445.                             nearLegComp->NextSeq->NextSeq->NextSeq->NextSeq;
  446.                         nearArmComp->AnimBob->Before = nearLegComp->AnimBob;
  447.                         nearLegComp->AnimBob->After = nearArmComp->AnimBob;
  448.  
  449.                         manOb->HeadComp = trunkComp;
  450.  
  451.                         trunkComp->PrevComp = NULL;
  452.                         trunkComp->NextComp = farArmComp;
  453.  
  454.                         farArmComp->PrevComp = trunkComp;
  455.                         farArmComp->NextComp = farLegComp;
  456.  
  457.                         farLegComp->PrevComp = farArmComp;
  458.                         farLegComp->NextComp = nearArmComp;
  459.  
  460.                         nearArmComp->PrevComp = farLegComp;
  461.                         nearArmComp->NextComp = nearLegComp;
  462.  
  463.                         nearLegComp->PrevComp = nearArmComp;
  464.                         nearLegComp->NextComp = NULL;
  465.  
  466.                         return(manOb);
  467.                         }
  468.                     freeSeq(nearArmComp,RBMDEPTH);
  469.                     }
  470.                 freeSeq(farLegComp,RBMDEPTH);
  471.                 }
  472.             freeSeq(farArmComp,RBMDEPTH);
  473.             }
  474.         freeSeq(trunkComp,RBMDEPTH);
  475.         }
  476.     FreeMem(manOb, (LONG)sizeof(struct AnimOb));
  477.     }
  478. return_code = RETURN_WARN;
  479. return(NULL);
  480. }
  481.  
  482. /*--------------------------------------------------------------
  483. ** setupBoing() - allocate and initialize an object that will
  484. ** display as an inch worm.
  485. **
  486. ** this is an animation object with only one animation sequence.
  487. **
  488. ** return NULL on failure.
  489. */
  490. struct AnimOb *setupWorm(SHORT dbufing)
  491. {
  492. struct AnimOb   *wormOb;
  493. struct AnimComp *wormComp;
  494.  
  495. if (NULL != (wormOb = AllocMem((LONG)sizeof(struct AnimOb), MEMF_CLEAR)))
  496.     {
  497.     wormOb->NextOb         = NULL;
  498.     wormOb->PrevOb         = NULL;
  499.     wormOb->Clock         = 0;
  500.     wormOb->AnY             = ((RBMHEIGHT - WRMHEIGHT - 5) << ANFRACSIZE);
  501.     wormOb->AnX             = (10L << ANFRACSIZE);
  502.     wormOb->AnOldY         = wormOb->AnY;
  503.     wormOb->AnOldX         = wormOb->AnX;
  504.     wormOb->YVel         = 0;
  505.     wormOb->XVel         = 0;
  506.     wormOb->YAccel         = 0;
  507.     wormOb->XAccel         = 0;
  508.     wormOb->RingYTrans     = (WRMRINGY << ANFRACSIZE);
  509.     wormOb->RingXTrans     = (WRMRINGX << ANFRACSIZE);
  510.     wormOb->AnimORoutine = anEdgeORoutine;
  511.     wormOb->AUserExt     = 0;
  512.  
  513.     newWrmBob.nb_DBuf     = dbufing;
  514.     newWrmSeq.nas_HeadOb = wormOb;
  515.  
  516.     if (NULL != (wormComp = makeSeq(&newWrmBob, &newWrmSeq)))
  517.         {
  518.         wormComp->Flags |= RINGTRIGGER;
  519.         wormOb->HeadComp = wormComp;
  520.  
  521.         return(wormOb);
  522.         }
  523.     }
  524. return_code = RETURN_WARN;
  525. return(NULL);
  526. }
  527.  
  528. /*--------------------------------------------------------------
  529. ** This ORoutine makes the Object restart on left edge if it has
  530. ** gone off the right of the screen. If it has gone off the top,
  531. ** it is restarted at the bottom. It is used for the worm and the
  532. ** man. It works for animations that move to the right, and
  533. ** optionally up, ONLY.
  534. */
  535. WORD anEdgeORoutine(struct AnimOb *anOb)
  536. {
  537. struct AnimComp *acptr;
  538. struct AnimComp *seqptr;
  539.  
  540. acptr = anOb->HeadComp;
  541.  
  542. while (acptr)
  543.     {
  544.     seqptr = acptr;
  545.     do    {
  546.         if (seqptr->AnimBob->BobVSprite->Flags & GELGONE)
  547.             {
  548.             seqptr->AnimBob->BobVSprite->Flags &= ~GELGONE;
  549.             anOb->AnX = -10L << ANFRACSIZE;
  550.             if (anOb->AnY <= 0)
  551.                 anOb->AnY = (RBMHEIGHT-60L) << ANFRACSIZE;
  552.             }
  553.         seqptr = seqptr->NextSeq;
  554.         } while (seqptr != acptr && (seqptr));
  555.     acptr = acptr->NextComp;
  556.     }
  557. return(0) ;
  558. }
  559.  
  560. /*--------------------------------------------------------------
  561. ** This ORoutine makes the Object Bounce off Borders.
  562. */
  563. WORD bounceORoutine(struct AnimOb *anOb)
  564. {
  565. SHORT Y;
  566. SHORT X;
  567.  
  568. Y = anOb->AnY >> ANFRACSIZE;
  569. X = anOb->AnX >> ANFRACSIZE;
  570.  
  571. if ((Y<0 && anOb->YVel < 0) ||
  572.     ((Y+anOb->HeadComp->AnimBob->BobVSprite->Height > RBMHEIGHT) &&
  573.      (anOb->YVel > 0)))
  574.     {
  575.     anOb->YVel = -(anOb->YVel);
  576.     }
  577.  
  578. if (((X < 0) && (anOb->XVel < 0)) ||
  579.     ((X + (anOb->HeadComp->AnimBob->BobVSprite->Width << 4) > RBMWIDTH) &&
  580.      (anOb->XVel > 0)))
  581.     {
  582.     anOb->XVel = -(anOb->XVel);
  583.     }
  584. return(0) ;
  585. }
  586.  
  587. /*--------------------------------------------------------------
  588. ** This CRoutine rearranges Bob Before and After pointers in a
  589. ** way that makes the Component passed look like it is in front
  590. ** of its' head component.
  591. ** 
  592. ** Used for Boing satelittes.
  593. ** 
  594. ** So that they go in front of AND behind the boing ball.
  595. */
  596. WORD goInFrontOfHead(struct AnimComp *aComp)
  597. {
  598. /* close up hole */
  599. if (aComp->AnimBob->Before != NULL)
  600.     aComp->AnimBob->Before->After = aComp->AnimBob->After;
  601. if (aComp->AnimBob->After != NULL)
  602.     aComp->AnimBob->After->Before = aComp->AnimBob->Before;
  603.  
  604. /* reinsert */
  605. aComp->AnimBob->Before = aComp->HeadOb->HeadComp->AnimBob->Before;
  606. aComp->AnimBob->After = aComp->HeadOb->HeadComp->AnimBob;
  607. if (aComp->AnimBob->Before != NULL)
  608.     aComp->AnimBob->Before->After = aComp->AnimBob;
  609. aComp->HeadOb->HeadComp->AnimBob->Before = aComp->AnimBob;
  610.  
  611. return(0) ;
  612. }
  613.  
  614. /*--------------------------------------------------------------
  615. ** This CRoutine rearranges Bob Before and After pointers in a
  616. ** way that makes the Component passed look like it is behind
  617. ** its' head component.
  618. */
  619. WORD goBehindHead(struct AnimComp *aComp)
  620. {
  621. if (aComp->AnimBob->Before != NULL)
  622.     aComp->AnimBob->Before->After = aComp->AnimBob->After;
  623. if (aComp->AnimBob->After != NULL)
  624.     aComp->AnimBob->After->Before = aComp->AnimBob->Before;
  625.  
  626. aComp->AnimBob->After = aComp->HeadOb->HeadComp->AnimBob->After;
  627. aComp->AnimBob->Before = aComp->HeadOb->HeadComp->AnimBob;
  628. if (aComp->AnimBob->After != NULL)
  629.     aComp->AnimBob->After->Before = aComp->AnimBob;
  630. aComp->HeadOb->HeadComp->AnimBob->After = aComp->AnimBob;
  631.  
  632. return(0) ;
  633. }
  634.  
  635. /*--------------------------------------------------------------
  636. **
  637. */
  638. VOID runAnimation(struct Window *win,
  639.                   SHORT dbufing,
  640.                   struct AnimOb **animKey,
  641.                   struct BitMap **myBitMaps)
  642. {
  643. struct IntuiMessage  *intuiMsg;
  644. WORD toggleFrame;
  645.  
  646. toggleFrame = 0;
  647.  
  648. /* everything opened, and allocated, and initialized.
  649. ** Now I just hang out, move the gels, tell the system to redraw them,
  650. ** and let the collision and anim routines bounce them about.
  651. */
  652. for (;;)
  653.     {
  654.     /* All the work done here */
  655.     DrawGels(win, animKey, dbufing, &toggleFrame, myBitMaps);
  656.  
  657.     while (intuiMsg = (struct IntuiMessage *)GetMsg(win->UserPort))
  658.         {
  659.         if (intuiMsg->Class == CLOSEWINDOW)
  660.             {
  661.             ReplyMsg((struct Message *)intuiMsg);
  662.             return;
  663.             }
  664.         ReplyMsg((struct Message *)intuiMsg);
  665.         }
  666.     }
  667. }
  668.  
  669. /*---------------------------------------------------------
  670. ** allocate the bit planes for a screen bit map.
  671. */
  672. LONG setupPlanes(struct BitMap *bitMap,
  673.                  LONG depth, LONG width, LONG height)
  674. {
  675. SHORT plane_num ;
  676.  
  677. for (plane_num = 0; plane_num < depth; plane_num++)
  678.     {
  679.     if (NULL != (bitMap->Planes[plane_num] =
  680.                     (PLANEPTR)AllocRaster(width, height)))
  681.         BltClear(bitMap->Planes[plane_num], (width / 8) * height, 1);
  682.     else
  683.         {
  684.         freePlanes(bitMap, depth, width, height);
  685.         return_code = RETURN_WARN;
  686.         return(NULL);
  687.         }
  688.     }
  689. return(TRUE);
  690. }
  691.  
  692. /*---------------------------------------------------------
  693. ** allocate the bit maps for a double buffered screen.
  694. */
  695. struct BitMap **setupBitMaps(LONG depth, LONG width, LONG height)
  696. {
  697. /* this must be static -- it cannot go away when the routine exits. */
  698. static struct BitMap *myBitMaps[2];
  699.  
  700. if (NULL != (myBitMaps[0] =
  701.         (struct BitMap *)AllocMem((LONG)sizeof(struct BitMap), MEMF_CLEAR)))
  702.     {
  703.     if (NULL != (myBitMaps[1] =
  704.         (struct BitMap *)AllocMem((LONG)sizeof(struct BitMap), MEMF_CLEAR)))
  705.         {
  706.         InitBitMap(myBitMaps[0], depth, width, height);
  707.         InitBitMap(myBitMaps[1], depth, width, height);
  708.  
  709.         if (NULL != setupPlanes(myBitMaps[0], depth, width, height))
  710.             {
  711.             if (NULL != setupPlanes(myBitMaps[1], depth, width, height))
  712.                 return(myBitMaps);
  713.  
  714.             freePlanes(myBitMaps[0], depth, width, height);
  715.             }
  716.         FreeMem(myBitMaps[1], (LONG)sizeof(struct BitMap));
  717.         }
  718.     FreeMem(myBitMaps[0], (LONG)sizeof(struct BitMap));
  719.     }
  720. return_code = RETURN_WARN;
  721. return(NULL);
  722. }
  723.  
  724. /*--------------------------------------------------------------
  725. ** free up the memory allocated by setupPlanes().
  726. */
  727. VOID    freePlanes(struct BitMap *bitMap,
  728.                    LONG depth, LONG width, LONG height)
  729. {
  730. SHORT plane_num ;
  731.  
  732. for (plane_num = 0; plane_num < depth; plane_num++)
  733.     {
  734.     if (NULL != bitMap->Planes[plane_num])
  735.         FreeRaster(bitMap->Planes[plane_num], width, height);
  736.     }
  737. }
  738.  
  739. /*--------------------------------------------------------------
  740. ** free up the memory allocated by setupBitMaps().
  741. */
  742. VOID    freeBitMaps(struct BitMap **myBitMaps,
  743.                     LONG depth, LONG width, LONG height)
  744. {
  745. freePlanes(myBitMaps[0], depth, width, height);
  746. freePlanes(myBitMaps[1], depth, width, height);
  747.  
  748. FreeMem(myBitMaps[0], (LONG)sizeof(struct BitMap));
  749. FreeMem(myBitMaps[1], (LONG)sizeof(struct BitMap));
  750. }
  751.  
  752. /*--------------------------------------------------------------
  753. **
  754. */
  755. struct GelsInfo *setupDisplay(struct Window **win,
  756.                               SHORT dbufing,
  757.                               struct BitMap **myBitMaps)
  758. {
  759. struct GelsInfo       *gInfo;
  760. struct Screen       *screen;
  761. struct ViewPort       *vport;
  762. struct RastPort    *rport;
  763.  
  764. if (dbufing)
  765.     {
  766.     /* Screen type. We alloc two BitMaps. See DBLBUF comments. */
  767.     ns.Type |= CUSTOMBITMAP;
  768.     ns.CustomBitMap = myBitMaps[0];
  769.     }
  770.  
  771. if ((screen = (struct Screen *)OpenScreen(&ns)) != NULL)
  772.     {
  773.     vport = &screen->ViewPort;
  774.     rport = &screen->RastPort;
  775.  
  776.     SetRGB4(vport, 0x0, 0x0, 0x0, 0x0); /* Black */
  777.     SetRGB4(vport, 0x1, 0x0, 0x6, 0x0); /* dk green */
  778.     SetRGB4(vport, 0x2, 0x0, 0x9, 0x0); /* med green */
  779.     SetRGB4(vport, 0x3, 0x0, 0xC, 0x0); /* lt green */
  780.     SetRGB4(vport, 0x4, 0x1, 0x1, 0x7); /* dk blue */
  781.     SetRGB4(vport, 0x5, 0x7, 0x0, 0x8); /* dk violet */
  782.     SetRGB4(vport, 0x6, 0x6, 0x6, 0x6); /* dk grey */
  783.     SetRGB4(vport, 0x7, 0x7, 0x1, 0x0); /* dk red */
  784.     SetRGB4(vport, 0x8, 0x3, 0x3, 0xB); /* med blue */
  785.     SetRGB4(vport, 0x9, 0xB, 0x0, 0xC); /* med violet */
  786.     SetRGB4(vport, 0xA, 0x9, 0x9, 0x9); /* med grey */
  787.     SetRGB4(vport, 0xB, 0xB, 0x0, 0x0); /* med red */
  788.     SetRGB4(vport, 0xC, 0x5, 0x5, 0xF); /* lt blue */
  789.     SetRGB4(vport, 0xD, 0xE, 0x0, 0xF); /* lt violet */
  790.     SetRGB4(vport, 0xE, 0xF, 0xF, 0xF); /* lt grey (white) */
  791.     SetRGB4(vport, 0xF, 0xF, 0x0, 0x0); /* lt red */
  792.  
  793.     /* put some stuff in the background, so we can
  794.     ** see that it does not get destroyed.
  795.     */
  796.     SetAPen(rport, 0xA);
  797.     SetDrMd(rport, JAM1);
  798.     Move(rport, 70, 105);
  799.     Text(rport, "Animation Example...", 20);
  800.  
  801.     nw.Screen = screen;
  802.     if ((*win = (struct Window *)OpenWindow(&nw)) != NULL)
  803.         {
  804.         if (dbufing)
  805.             {
  806.             (*win)->WScreen->RastPort.Flags = DBUFFER;
  807.  
  808.             /* copy the rast port data into the alternate rast port */
  809.             (*win)->WScreen->RastPort.BitMap = myBitMaps[1];
  810.             BltBitMapRastPort(myBitMaps[0], 0,0, &(*win)->WScreen->RastPort,
  811.                         0,0, RBMWIDTH, RBMHEIGHT, 0xC0);
  812.             (*win)->WScreen->RastPort.BitMap = myBitMaps[0];
  813.             }
  814.  
  815.         /* set up the gels system.
  816.         ** 0x03 says: when you allocate sprites for me, don't ever use
  817.         ** sprites zero or one. This guarantees that sprite zero, the
  818.         ** intuition pointer, stays intact. Remember sprite one shares
  819.         ** colors with sprite zero.
  820.         */
  821.         if (NULL != (gInfo = setupGelSys(&(*win)->WScreen->RastPort, 0x03)))
  822.             return(gInfo);
  823.  
  824.         CloseWindow(*win);
  825.         }
  826.     CloseScreen(screen);
  827.     }
  828. return_code = RETURN_WARN;
  829. return(NULL);
  830. }
  831.  
  832. /*--------------------------------------------------------------
  833. ** DrawGels part of loop.
  834. */
  835. VOID DrawGels(struct Window *win,
  836.               struct AnimOb **animKey,
  837.               SHORT dbufing,
  838.               WORD *toggleFrame,
  839.               struct BitMap **myBitMaps)
  840. {
  841. Animate(animKey, &win->WScreen->RastPort);
  842.  
  843. SortGList(&win->WScreen->RastPort);   /* Put the list in order. */
  844. DoCollision(&win->WScreen->RastPort); /* Collision routines may called now */
  845. SortGList(&win->WScreen->RastPort);      /* Put the list in order. */
  846.  
  847. if (dbufing)
  848.     win->WScreen->ViewPort.RasInfo->BitMap = myBitMaps[*toggleFrame];
  849.  
  850. /* Draw 'em. */
  851. DrawGList(&win->WScreen->RastPort, &win->WScreen->ViewPort);
  852.  
  853. if (dbufing)
  854.     {
  855.     MakeScreen(win->WScreen);    /* Tell intuition to do it's stuff. */
  856.     RethinkDisplay();            /* Does a MrgCop & LoadView. */
  857.  
  858.     *toggleFrame ^= 1;
  859.     /* Flip to the next BitMap. */
  860.     win->WScreen->RastPort.BitMap = myBitMaps[*toggleFrame];
  861.     }
  862. else
  863.     WaitTOF();
  864. }
  865.  
  866. /*--------------------------------------------------------------
  867. **
  868. */
  869. VOID main(int argc, char **argv)
  870. {
  871. struct BitMap    **myBitMaps;
  872. struct AnimOb     *boingOb;
  873. struct AnimOb     *wormOb;
  874. struct AnimOb     *manOb;
  875. struct Window     *win;
  876. struct Screen     *screen;
  877. struct GelsInfo     *gInfo;
  878. struct AnimOb     *animKey;
  879. SHORT dbufing;
  880.  
  881. return_code = RETURN_OK; /* a global variable, yech! */
  882.  
  883.  
  884. if (argc > 1)
  885.     dbufing = 1;  /* run double buffered when arguments */
  886. else
  887.     {
  888.     dbufing = 0;  /* not double buff */
  889.     if (argc)
  890.         printf("Program will run double buffered if there are\nany command line arguments.\n");
  891.     }
  892.  
  893. if (NULL == (IntuitionBase = (struct IntuitionBase *)
  894.         OpenLibrary(INTUITIONNAME, 34L)))
  895.     return_code = RETURN_FAIL;
  896. else
  897.     {
  898.     if (NULL == (GfxBase = (struct GfxBase *)
  899.             OpenLibrary(GRAPHICSNAME, 34L)))
  900.         return_code = RETURN_FAIL;
  901.     else
  902.         {
  903.         if ((!dbufing) ||
  904.             (NULL != (myBitMaps=setupBitMaps(RBMDEPTH,RBMWIDTH,RBMHEIGHT))))
  905.             {
  906.             if (NULL != (gInfo = setupDisplay(&win,dbufing,myBitMaps)))
  907.                 {
  908.                 InitAnimate(&animKey);
  909.                 /* Simple sequenced animation. (Boing ball)
  910.                 ** Simple animation using XTrans and YTrans.
  911.                 ** (tiny orbiting satellite)
  912.                 */
  913.                 if (NULL != (boingOb = setupBoing(dbufing)))
  914.                     {
  915.                     AddAnimOb(boingOb, &animKey, &win->WScreen->RastPort);
  916.                     if (NULL != (wormOb = setupWorm(dbufing)))
  917.                         {
  918.                         AddAnimOb(wormOb, &animKey, &win->WScreen->RastPort);
  919.                         if (NULL != (manOb = setupMan(dbufing)))
  920.                             {
  921.                             AddAnimOb(manOb, &animKey,
  922.                                         &win->WScreen->RastPort);
  923.                             runAnimation(win, dbufing, &animKey, myBitMaps);
  924.                             freeOb(manOb, RBMDEPTH);
  925.                             }
  926.                         freeOb(wormOb, RBMDEPTH);
  927.                         }
  928.                     freeOb(boingOb, RBMDEPTH);
  929.                     }
  930.  
  931.                 cleanupGelSys(gInfo, &win->WScreen->RastPort);
  932.                 screen = win->WScreen;
  933.                 CloseWindow(win);
  934.                 CloseScreen(screen);
  935.                 }
  936.  
  937.             if (dbufing)
  938.                 freeBitMaps(myBitMaps, RBMDEPTH, RBMWIDTH, RBMHEIGHT);
  939.             }
  940.         CloseLibrary((struct Library *)GfxBase);
  941.         }
  942.     CloseLibrary((struct Library *)IntuitionBase);
  943.     }
  944. exit(return_code);
  945. }
  946.